const { Document } = require('camo')
const Character = require('./character')

const tinycolor = require('tinycolor2')
const chalk = require('chalk')

// Just an organised party (read: team, group) of Characters.
class Party extends Document {
  constructor() {
    super()

    this.schema({
      members: [Character],
      name: {type: String, default: 'Unnamed Party'},
      colorHue: {type: Number, min: 0, max: 1},
      discordRoleID: {type: String, required: false}, // Will be automatically generated
    })
  }

  addCharacter(character) {
    this.members.push(character)

    character.partyID = this
  }

  async getRole(guild) {
    // Create the role, if it doesn't exist already.
    if (!this.discordRoleID) {
      const role = await guild.createRole()
      await this.updateRole(role)

      this.discordRoleID = role.id
    }

    return guild.roles.get(this.discordRoleID)
  }

  async updateRole(role) {
    // Update party role details.
    await role.edit({
      name: 'Party: ' + this.name,
      color: tinycolor.fromRatio({h: this.colorHue, s: 0.6, v: 1.0}).toHexString()
    })
  }

  async assignRoles(guild) {
    const partyRole = await this.getRole(guild)
    await this.updateRole(partyRole)

    for (const character of this.members) {
      if (!character.discordID) {
        continue
      }

      const member = guild.members.get(character.discordID)
      member.addRole(partyRole)
    }
  }

  static of(characters) {
    const party = this.create({
      characters: [],
      colorHue: Math.random()
    })

    for (const character of characters) {
      party.addCharacter(character)
    }

    return party
  }

  static async cleanDeadRoles(guild, log) {
    const partyRoles = guild.roles.filter(role => role.name.startsWith('Party:')).array()

    for (const role of partyRoles) {
      const party = await this.findOne({discordRoleID: role.id})
      if (!party) {
        await role.delete()
        log.info(`Deleted unused party role ${chalk.blue(role.name)}`)
      }
    }
  }
}

module.exports = Party
